Remove remaining callers and definition of rtrim.
* Minor CV-qualifier battle in jeeps for const correctness.
* Adds a (hacky) bash script to compile mkshort as a standalone binary for
development and testing for upcoming overhaul.
---------
Co-authored-by: Robert Lipe <robertlipe@gmail.com>
int str_match(const char* str, const char* match);
-void rtrim(char* s);
int xasprintf(char** strp, const char* fmt, ...) PRINTFLIKE(2, 3);
int xasprintf(QString* strp, const char* fmt, ...) PRINTFLIKE(2, 3);
int xasprintf(QScopedPointer<char, QScopedPointerPodDeleter>& strp, const char* fmt, ...) PRINTFLIKE(2, 3);
#define MAX_HEADER_FIELDS 36
-static char* header_lines[unknown_header + 1][MAX_HEADER_FIELDS];
+static QString header_lines[unknown_header + 1][MAX_HEADER_FIELDS];
static int header_fields[unknown_header + 1][MAX_HEADER_FIELDS];
static int header_ct[unknown_header + 1];
free_header(const header_type ht)
{
for (int i = 0; i < MAX_HEADER_FIELDS; i++) {
- char* c = header_lines[ht][i];
- if (c != nullptr) {
- xfree(c);
- header_lines[ht][i] = nullptr;
- }
+ header_lines[ht][i].clear();
}
header_ct[ht] = 0;
memset(header_fields[ht], 0, sizeof(header_fields[ht]));
for (const auto& str : lineparts) {
column++;
- header_lines[unknown_header][column] = strupper(xstrdup(str));
+ header_lines[unknown_header][column] = str;
+ header_lines[unknown_header][column] = header_lines[unknown_header][column].toUpper();
header_ct[unknown_header]++;
if (header_ct[unknown_header] >= MAX_HEADER_FIELDS) {
break;
}
for (i = 0; i < header_ct[unknown_header]; i++) {
- char* name = header_lines[ht][i] = header_lines[unknown_header][i];
- header_lines[unknown_header][i] = nullptr;
+ auto name = header_lines[ht][i] = header_lines[unknown_header][i];
+ header_lines[unknown_header][i].clear();
c = fields;
int field_no = 1;
while (*c) {
- if (strcmp(c, name) == 0) {
+ if (name.compare(c) == 0) {
header_fields[ht][i] = field_no;
#if 0
printf("Binding field \"%s\" to internal number %d (%d,%d)\n", name, field_no, ht, i);
** Convert Ordnance Survey map eastings and northings plus
** two letter code to Airy 1830 eastings and northings
**
-** @param [w] map [char *] map code
+** @param [w] map [const char *] map code
** @param [r] mapE [double] easting (metres)
** @param [r] mapN [double] northing (metres)
** @param [w] E [double *] full Airy easting (metres)
**
** @return [int32] success
************************************************************************/
-int32 GPS_Math_UKOSNG_Map_To_EN(char* map, double mapE, double mapN, double* E,
- double* N)
+int32 GPS_Math_UKOSNG_Map_To_EN(const char* map, double mapE, double mapN,
+ double* E, double* N)
{
int32 t;
int32 idx;
** Transform UK Ordnance survey map position to WGS84 lat/lon
** Uses Molodensky transformation
**
-** @param [r] map [char *] map two letter code
+** @param [r] map [const char *] map two letter code
** @param [r] mE [double] map easting (metres)
** @param [r] mN [double] map northing (metres)
** @param [w] lat [double *] WGS84 latitude (deg)
**
** @return [int32] success
************************************************************************/
-int32 GPS_Math_UKOSMap_To_WGS84_M(char* map, double mE, double mN,
+int32 GPS_Math_UKOSMap_To_WGS84_M(const char* map, double mE, double mN,
double* lat, double* lon)
{
double E;
**
** @return [int32] success
************************************************************************/
-int32 GPS_Math_UKOSMap_To_WGS84_C(char* map, double mE, double mN,
+int32 GPS_Math_UKOSMap_To_WGS84_C(const char* map, double mE, double mN,
double* lat, double* lon)
{
double E;
double* N);
int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double* mE,
double* mN, char* map);
- int32 GPS_Math_UKOSNG_Map_To_EN(char* map, double mapE, double mapN,
+ int32 GPS_Math_UKOSNG_Map_To_EN(const char* map, double mapE, double mapN,
double* E, double* N);
void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H,
int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double* mE,
double* mN, char* map);
- int32 GPS_Math_UKOSMap_To_WGS84_M(char* map, double mE, double mN,
+ int32 GPS_Math_UKOSMap_To_WGS84_M(const char* map, double mE, double mN,
double* lat, double* lon);
int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double* mE,
double* mN, char* map);
- int32 GPS_Math_UKOSMap_To_WGS84_C(char* map, double mE, double mN,
+ int32 GPS_Math_UKOSMap_To_WGS84_C(const char* map, double mE, double mN,
double* lat, double* lon);
}
}
+ /* Eliminate trailing whitespace in all cases. This is done late because
+ earlier operations may have vacated characters after the space. */
+
+ char *end = ostring + strlen(ostring) - 1;
+ while (end > ostring && isspace(*end)) {
+ *end-- = 0;
+ }
+
+
/*
* Toss vowels to approach target length, but don't toss them
* if we don't have to. We always keep the leading two letters
}
memmove(dp, np, nlen);
dp[nlen] = 0;
- rtrim(ostring);
+ // Essentially ostring.rtrim() from here down.
+ if (ostring && ostring[0] != 0) { // Empty output string? Bail.
+ char *end = ostring + strlen(ostring) - 1;
+ while (end > ostring && isspace(*end)) {
+ *end-- = 0;
+ }
+ }
}
/*
* If, after all that, we have an empty string, punt and
* let the must_uniq code handle it.
*/
- if (ostring[0] == '\0') {
+ if (ostring && ostring[0] == '\0') {
xfree(ostring);
ostring = xstrdup(hdl->defname);
}
}
-#if 0
-char* foo[] = {
+#if TEST_MKSHORT
+const char* foo[] = {
"VwthPst# 3700.706N 08627.588W 0000000m View the Past #2 ",
"PilotRoc 3655.270N 08717.173W 0000000m Pilot Rock by CacheAdvance ",
"MrCycsNg 3652.407N 08728.890W 0000000m Mr. Cayces Neighborhood by Ca",
"GimmShlt 3430.087N 08536.834W 0000000m Gimme Shelter by Big Rock & Po",
"GnomeTrs 3433.081N 08535.849W 0000000m Gnome Treasure by Big Rock ",
"FlyingTr 3608.594N 08648.179W 0000000m Flying Torso by Campaholics ",
- "CultivtC 3608.582N 08648.064W 0000000m Cultivate a Cure by Campahol"
+ "CultivtC 3608.582N 08648.064W 0000000m Cultivate a Cure by Campahol",
+ __nullptr
}
;
-main()
+int main()
{
- char** foop = foo;
int r;
- printf("%s\n", mkshort("The Troll"));
- printf("%s\n", mkshort("EFI"));
- printf("%s\n", mkshort("the Troll"));
- printf("%s\n", mkshort("the Trolley"));
- printf("%s\n", mkshort("The Troll Lives Under The Bridge"));
- printf("%s\n", mkshort("The \"Troll\" Lives Under $$ The Bridge!"));
- printf("%s\n", mkshort("The Trolley Goes Round"));
- printf("%s\n", mkshort("Cache In / Trash Out #1"));
- printf("%s\n", mkshort("Cache In / Trash Out #2"));
- printf("%s\n", mkshort("Cache In / Trash Out #137"));
-
- while (0 && *foop) {
- printf("%s %s\n", mkshort(*foop+39), *foop+39);
+ auto h = mkshort_new_handle();
+// setshort_whitespace_ok(h, false);
+
+ printf("%s\n", mkshort(h, "The Troll", false));
+ printf("%s\n", mkshort(h, "EFI", false));
+ printf("%s\n", mkshort(h, "the Troll", false));
+ printf("%s\n", mkshort(h, "the Trolley", false));
+ printf("%s\n", mkshort(h, "The Troll Lives Under The Bridge", false));
+ printf("%s\n", mkshort(h, "The \"Troll\" Lives Under $$ The Bridge!", false));
+ printf("%s\n", mkshort(h, "The Trolley Goes Round", false));
+ printf("%s\n", mkshort(h, "Cache In / Trash Out #1", false));
+ printf("%s\n", mkshort(h, "Cache In / Trash Out #2", false));
+ printf("%s\n", mkshort(h, "Cache In / Trash Out #137", false));
+ printf("|%s|\n", mkshort(h, "Cache .", false));
+ printf("|%s|\n", mkshort(h, "Cache .", false));
+ printf("|%s|\n", mkshort(h, "Cache .", false));
+ printf("|%s|\n", mkshort(h, " Cache .", false));
+
+#if 0
+ const char** foop = foo;
+ while (*foop) {
+ printf("%s | %s\n", mkshort(h, *foop+39, false), *foop+39);
foop++;
}
+#endif
- printf("%s\n", delete_last_vowel(0, "the quick brown foo", &r));
- printf("%s\n", delete_last_vowel(0, "the quick brown fox", &r));
- printf("%s\n", delete_last_vowel(0, "xxx", &r));
- printf("%s\n", delete_last_vowel(0, "ixxx", &r));
- printf("%s\n", delete_last_vowel(0, "aexxx", &r));
+ printf("%s\n", delete_last_vowel(0, xstrdup("the quick brown foo"), &r));
+ printf("%s\n", delete_last_vowel(0, xstrdup("the quick brown fox"), &r));
+ printf("%s\n", delete_last_vowel(0, xstrdup("xxx"), &r));
+ printf("%s\n", delete_last_vowel(0, xstrdup("ixxx"), &r));
+ printf("%s\n", delete_last_vowel(0, xstrdup("aexxx"), &r));
+ return 0;
}
#endif
--- /dev/null
+#
+# Definitely a kludge, but build mkshort in a way that the output can be run
+# and visually inspected. Unlikely to work for anyone but robert.
+#
+
+c++ \
+ -DTEST_MKSHORT \
+ -DCSVFMTS_ENABLED \
+ -DFILTERS_ENABLED \
+ -DHAVE_LIBUSB_1_0 \
+ -DLIBUSB_H_INCLUDE=\"mac/libusb/libusb.h\" \
+ -DMAXIMAL_ENABLED \
+ -DQT_CORE5COMPAT_LIB \
+ -DQT_CORE_LIB \
+ -DQT_NO_DEBUG \
+ -DSHAPELIB_ENABLED \
+ -I. \
+ -isystem /opt/homebrew/opt/qt/lib/QtCore.framework/Headers -iframework /opt/homebrew/opt/qt/lib -isystem /opt/homebrew/opt/qt/share/qt/mkspecs/macx-clang -isystem /opt/homebrew/opt/qt/include -isystem /opt/homebrew/opt/qt/lib/QtCore5Compat.framework/Headers -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk \
+ -Wall \
+ -Wsign-compare \
+ -std=gnu++17 \
+ -Winvalid-pch \
+ -Xarch_arm64 \
+ -include/Users/robertlipe/src/gpsbabel/CMakeFiles/gpsbabel.dir/cmake_pch_arm64.hxx \
+ -o short_test \
+ mkshort.cc util.cc fatal.cc \
+ -F/opt/homebrew/opt/qt/lib \
+ -Wl,-rpath,/opt/homebrew/opt/qt/lib /opt/homebrew/opt/qt/lib/QtCore5Compat.framework/Versions/A/QtCore5Compat libshp.a \
+ libz.a libusb-1.0.a \
+ /opt/homebrew/opt/qt/lib/QtCore.framework/Versions/A/QtCore \
+ -framework DiskArbitration -lobjc \
+ -framework IOKit \
+ -framework CoreFoundation \
+ -framework Security
+
+
+# -MD -MT CMakeFiles/gpsbabel.dir/mkshort.cc.o \
+# -MF CMakeFiles/gpsbabel.dir/mkshort.cc.o.d \
const field_t* f = &fields_def[0];
unicsv_fields_tab.append(fld_terminator);
- while (f->name) {
+ while (!f->name.isEmpty()) {
if (unicsv_compare_fields(value, f)) {
unicsv_fields_tab.last() = f->type;
break;
}
f++;
}
- if ((! f->name) && global_opts.debug_level) {
+ if ((f->name.isEmpty()) && global_opts.debug_level) {
warning(MYNAME ": Unhandled column \"%s\".\n", qPrintable(value));
}
double utm_easting = 0;
double utm_northing = 0;
char utm_zc = 'N';
- // Zones are always two bytes. Spare one for null termination..
- char bng_zone[3] = "";
+ // Zones are always two bytes.
+ QString bng_zone;
double bng_easting = kUnicsvUnknown;
double bng_northing = kUnicsvUnknown;
double swiss_easting = kUnicsvUnknown;
break;
case fld_bng_zone:
- strncpy(bng_zone, CSTR(value), sizeof(bng_zone) - 1);
- strupper(bng_zone);
+ bng_zone = value.toUpper();
break;
case fld_bng_northing:
GPS_Math_UTM_EN_To_Known_Datum(&wpt->latitude, &wpt->longitude,
utm_easting, utm_northing, utm_zone, utm_zc, unicsv_datum_idx);
} else if ((bng_easting != kUnicsvUnknown) && (bng_northing != kUnicsvUnknown)) {
- if (bng_zone[0] == '\0') { // OS easting northing
+ if (bng_zone.isEmpty()) { // OS easting northing
// Grid references may also be quoted as a pair of numbers: eastings then northings in metres, measured from the southwest corner of the SV square.
double bnge;
double bngn;
bngz, bnge, bngn);
} else { // traditional zone easting northing
if (! GPS_Math_UKOSMap_To_WGS84_M(
- bng_zone, bng_easting, bng_northing,
+ CSTR(bng_zone), bng_easting, bng_northing,
&wpt->latitude, &wpt->longitude))
fatal(MYNAME ": Unable to convert BNG coordinates (%s %.f %.f)!\n",
- bng_zone, bng_easting, bng_northing);
+ CSTR(bng_zone), bng_easting, bng_northing);
}
src_datum = kDautmWGS84; /* don't convert afterwards */
} else if ((swiss_easting != kUnicsvUnknown) && (swiss_northing != kUnicsvUnknown)) {
};
struct field_t {
- const char* name;
+ const QString name;
field_e type;
uint32_t options;
};
return outsize;
}
-void
-rtrim(char* s)
-{
- char* t = s;
-
- if (!s || !*s) {
- return;
- }
-
- while (*s) {
- s++;
- }
-
- s--;
- while ((s >= t) && isspace(*s)) {
- *s = 0;
- s--;
- }
-}
-
/*
* compare str with match
* match may contain wildcards "*" and "?"